package com.lzy.product.apis.impl;

import com.github.pagehelper.PageInfo;
import com.lzy.base.apis.SysUserAdminServiceApi;
import com.lzy.base.dtos.SysUserAdminDto;
import com.lzy.framework.core.ensure.Ensure;
import com.lzy.framework.core.exceptions.XBusinessException;
import com.lzy.framework.core.orm.db.Pager;
import com.lzy.framework.tools.commons.BigDecimalUtil;
import com.lzy.product.apis.DeptDividedServiceApi;
import com.lzy.product.apis.OrderProfitServiceApi;
import com.lzy.product.apis.ProductInfoServiceApi;
import com.lzy.product.constants.BusinessType.ProfitErrorStatus;
import com.lzy.product.constants.profit.ProfitConstants;
import com.lzy.product.constants.profit.ProfitTargetEnum;
import com.lzy.product.dtos.DeptDividedDto;
import com.lzy.product.dtos.ProductInfoDto;
import com.lzy.product.dtos.profit.ProfitErrorDto;
import com.lzy.product.dtos.profit.ProfitParamDto;
import com.lzy.product.dtos.statistics.OrderProfitRecordDto;
import com.lzy.product.service.OrderProfitRecordService;
import com.lzy.product.service.ProfitErrorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * 分利
 * Created by WIN7 on 2017/12/4.
 */
@Service
public class OrderProfitServiceApiImpl implements OrderProfitServiceApi {
    private static final Logger LOGGER = LoggerFactory.getLogger(OrderProfitServiceApiImpl.class);

    @Autowired
    private ProductInfoServiceApi productInfoServiceApi;
    @Autowired
    private SysUserAdminServiceApi sysUserAdminServiceApi;
    @Autowired
    private DeptDividedServiceApi deptDividedServiceApi;
    @Autowired
    private ProfitErrorService profitErrorService;
    @Autowired
    private OrderProfitRecordService orderProfitRecordService;

    @Override
    public Boolean calculate(ProfitParamDto profitParamDto) {
        Boolean flag = true;
        //订单ID必须传入
        Ensure.that(profitParamDto.getOrderId()).isNotNull("13020001");
        //判断是否已经分利
        List<OrderProfitRecordDto> recordDtos = orderProfitRecordService.findByOrderId(profitParamDto.getOrderId());
        if (recordDtos == null || recordDtos.size() == 0) {
            try {
                //查询产品波比值
                Ensure.that(profitParamDto.getSkuCode()).isNotNull("13020002");
                ProductInfoDto productInfoDto = productInfoServiceApi.findById(profitParamDto.getSkuCode());
                Ensure.that(productInfoDto).isNotNull("01000002");

                if (!BigDecimalUtil.isZeroOrNull(productInfoDto.getProfit())
                        && !BigDecimalUtil.isZeroOrNull(profitParamDto.getOrderMoney())) {
                    BigDecimal proportion = BigDecimalUtil.multiply(productInfoDto.getProfit(), new BigDecimal("0.01"));
                    //查询产品波比值
                    Ensure.that(profitParamDto.getUserId()).isNotNull("13020003");
                    //一级业务员
                    SysUserAdminDto firstDto = sysUserAdminServiceApi.selectByPrimaryKey(profitParamDto.getUserId());
                    Ensure.that(firstDto).isNotNull("11040000");
                    //查询部门分利比例
                    DeptDividedDto dividedDto = deptDividedServiceApi.findByDeptId(firstDto.getDeptId());
                    Ensure.that(dividedDto).isNotNull("11040001");

                    //记录公用信息
                    OrderProfitRecordDto dto = new OrderProfitRecordDto();
                    dto.setOrderId(profitParamDto.getOrderId());
                    if (profitParamDto.getOrderTime() != null) {
                        dto.setOrderTime(profitParamDto.getOrderTime().substring(0, 16));
                    }
                    //订单业务员ID
                    dto.setOrderUserId(profitParamDto.getUserId());
                    dto.setOrderUserName(firstDto.getRealName());
                    //商品ID、名称
                    dto.setSkuCode(profitParamDto.getSkuCode());
                    dto.setSkuName(productInfoDto.getName());

                    //新增一级业务员分利记录
                    dto.setLevel(ProfitTargetEnum.ONE_LEVEL.getCode());
                    BigDecimal firstProfit = putProfitLayerVo(dividedDto.getOneLevel(), BigDecimalUtil.multiply(profitParamDto.getOrderMoney(), proportion), firstDto, dto);
                    if (firstProfit.compareTo(BigDecimal.ZERO) > 0) {
                        orderProfitRecordService.insert(dto);
                    }

                    Long superId = firstDto.getUserId();
                    //循环查询上级
                    for (int i = 2; i <= ProfitConstants.PROFIT_LAYER; i++) {
                        SysUserAdminDto userAdminDto = null;
                        BigDecimal layerProfit = BigDecimal.ZERO;
                        //避免多余的查询
                        if (superId != ProfitConstants.PLATFORM) {
                            userAdminDto = sysUserAdminServiceApi.selectByPrimaryKey(superId);
                        }
                        if (userAdminDto == null) {
                            //平台用户
                            userAdminDto = new SysUserAdminDto();
                            userAdminDto.setId(ProfitConstants.PLATFORM);
                            userAdminDto.setRealName(ProfitConstants.PLATFORM_STR);
                            superId = ProfitConstants.PLATFORM;
                        } else {
                            superId = userAdminDto.getUserId();
                        }
                        if (i == 2) {
                            dto.setLevel(ProfitTargetEnum.TWO_LEVEL.getCode());
                            layerProfit = putProfitLayerVo(dividedDto.getTwoLevel(), BigDecimalUtil.multiply(profitParamDto.getOrderMoney(), proportion), userAdminDto, dto);
                        } else if (i == 3) {
                            dto.setLevel(ProfitTargetEnum.THREE_LEVEL.getCode());
                            layerProfit = putProfitLayerVo(dividedDto.getThreeLevel(), BigDecimalUtil.multiply(profitParamDto.getOrderMoney(), proportion), userAdminDto, dto);
                        }

                        if (layerProfit.compareTo(BigDecimal.ZERO) > 0) {
                            orderProfitRecordService.insert(dto);
                        }
                    }
                }
            } catch (XBusinessException e) {
                flag = false;
                //保存错误记录
                saveProfit(profitParamDto.getOrderId(), e.getXCode(), e.getMessageWithoutCode());
                LOGGER.error(profitParamDto.getOrderId() + "-订单分利出错啦，错误详情：" + e.getMessage());
            } catch (Exception e) {
                flag = false;
                //保存错误记录
                saveProfit(profitParamDto.getOrderId(), null, e.getMessage());
                LOGGER.error(profitParamDto.getOrderId() + "-订单分利出错啦，错误详情：" + e.getMessage());
            }

        }

        //处理成功
        if (flag && profitErrorService.findById(profitParamDto.getOrderId()) != null) {
            dealProfit(profitParamDto.getOrderId(), ProfitErrorStatus.DEAL_SUCCESS.getCode());
        }
        return flag;
    }

    @Override
    public PageInfo<OrderProfitRecordDto> queryRecordList(Pager pager, OrderProfitRecordDto paramDto) {
        return orderProfitRecordService.selectList(pager, paramDto);
    }

    @Override
    public PageInfo<ProfitErrorDto> queryErrorList(Pager pager, ProfitErrorDto paramDto) {
        return profitErrorService.selectList(pager, paramDto);
    }

    @Override
    public Boolean dealProfit(Long orderId, Integer status) {
        ProfitErrorDto profitErrorDto = new ProfitErrorDto();
        profitErrorDto.setOrderId(orderId);
        profitErrorDto.setStatus(status);
        return profitErrorService.update(profitErrorDto);
    }

    /**
     * 层级分利封装
     *
     * @param proportion   层级占比
     * @param profitMoney  分利金额
     * @param userAdminDto 用户
     * @param recordDto    封装记录
     * @return
     */
    private BigDecimal putProfitLayerVo(BigDecimal proportion, BigDecimal profitMoney, SysUserAdminDto userAdminDto, OrderProfitRecordDto recordDto) {
        recordDto.setUserId(userAdminDto.getId());
        recordDto.setUserName(userAdminDto.getRealName());
        BigDecimal layerProfit = BigDecimal.ZERO;
        if (!BigDecimalUtil.isZeroOrNull(proportion)) {
            layerProfit = BigDecimalUtil.to2Point(BigDecimalUtil.multiply(profitMoney, proportion));
        }
        recordDto.setProfit(layerProfit);
        return layerProfit;
    }

    /**
     * 保存分利错误记录
     *
     * @param orderId 订单号
     * @param code    错误码
     * @param msg     错误详情
     */
    private void saveProfit(Long orderId, String code, String msg) {
        if (msg.length() > 200) {
            msg = msg.substring(30, 230);
        }
        //计算重新添加
        ProfitErrorDto profitErrorDto = new ProfitErrorDto();
        profitErrorDto.setOrderId(orderId);
        profitErrorDto.setErrorCode(code);
        profitErrorDto.setErrorMsg(msg);
        if (profitErrorService.findById(orderId) == null) {
            profitErrorService.insert(profitErrorDto);
        } else {
            profitErrorDto.setStatus(ProfitErrorStatus.DEAL_FAILED.getCode());
            profitErrorService.update(profitErrorDto);
        }
    }
}
